
public class Memory {
	
	private final int ILEGAL_ACESS = -1; 
	
	// This is the memory system component. 
	  @SuppressWarnings("unused")
	  private IntController hint;
	  private int[] memoryWord;
	  private int memorySize;
	  
	
	  // constructor
	  public Memory(IntController i,int s)
	  {
	    // remember size and create memory
	    hint = i;
	    memorySize = s;
	    memoryWord = new int[s];
	 
	    //LOADED Processes on Boot:
	    init(0,'J','P','A',0); //dummy
	    
	    init(257,'J','P','A',3); //P1
	    init(258,0,0,0,2); 
	    init(259,0,0,0,25);
	    init(260,'L','M',0,1);
	    init(261,'L','M',1,2);
	    init(262,'A','D',0,1);
	    init(263,'W','M',0,1);
	    init(264,'I','N','T',32);
	    
	    init(385,'J','P','A',130); // P2 - To simulate a invalid memory access
	    init(386,'I','N','T',32);
	    
	    init(513,0,0,0,0); //READ OP
	    init(514,0,0,0,0); //Disk0
	    init(515,0,0,0,1); //Disk initialfile
	    init(516,'L','M',0,0); //Reg0  = READ OP
	    init(517,'L','M',1,1); //Reg 1 = Disk 0
	    init(518,'L','M',2,2); //Reg 2 = Diks initialfile 1
	    init(519,'I','N','T',34); //OPEN
	    init(520,'I','N','T',36); //GET
	    init(521,0,0,0,1); //WRITE OP
	    init(522,0,0,0,1); //Disk1
	    init(523,0,0,0,0); //Disk initialfile
	    init(524,'L','M',0,8); //Reg0  = Write OP
	    init(525,'L','M',1,9); //Reg1 = Disk 1
	    init(526,'L','M',2,10); //Reg 2 = Diks initialfile 1
	    init(527,'I','N','T',34); //OPEN
	    init(528,0,0,0,78); //DATA == 42
	    init(529,'L','M',1,15); //Reg1 == 42
	    init(530,'I','N','T',37); //PUT
	    init(531,'I','N','T',35); //CLOSE. One file keep opened, and the most recent one closes
	    init(532,'I','N','T',32); //Finish process
	    
	    //print();
	  }
	  
	  //Access Methods for kernel
	  public synchronized int superRead(int address)
	  {
		  //Sanity
		  if( (address > 0) && (address < memorySize) )
			  return memoryWord[address];
		  else
		  {
			  //hint.set(ILEGAL_ACESS);
		  	  return ILEGAL_ACESS;
		  }
	  }
	  
	  public synchronized int superWrite(int address, int data)
	  {  
		  //Sanity
		  if( (address > 0) && (address < memorySize) )
		  {
			  memoryWord[address] = data;
			  return 0;
		  }
		  else
			  //hint.set(ILEGAL_ACESS);
			  return ILEGAL_ACESS;
	  }	  
	  
	  public synchronized void init(int add, int a, int b, int c, int d)
	  {
	    memoryWord[add] = (a << 24)+(b<<16)+(c<<8)+d;
	    //System.out.println("Linha da memoria: " + memoryWord[add] );
	  } 
	  
	  public synchronized int readfromPC(int address, Process p)
	  {
	    if (address >= p.LimitRegister)
	    {
	      //hint.set(ILEGAL_ACESS);
	      return ILEGAL_ACESS;
	    }
	    else
	      return memoryWord[address];
	  }
	  
	  public synchronized int read(int address, Process p)
	  {
	    if (address >= p.LimitRegister)
	    {
	      //hint.set(ILEGAL_ACESS);
	      return ILEGAL_ACESS;
	    }
	    else
	      return memoryWord[p.BaseRegister + address];
	  }
	  
	  public synchronized int write(int address, int data, Process p)
	  {
	    if (address >= p.LimitRegister)
	    {
	      //hint.set(ILEGAL_ACESS);
	      return ILEGAL_ACESS;
	    }
	    else
	    {
	      memoryWord[p.BaseRegister + address] = data;
	      return 0;
	    }
	 }
	  
	  public synchronized void print()
	  {
		  System.out.println("MEMORY: ");
		  for(int i=0; i <  memorySize; i++)
		  {
			  if(memoryWord[i] >= 0)
				  System.out.println("Index "+ i + " = "+memoryWord[i]);
		  }
	  }
}
